package com.zsk.tool.thread;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * https://www.cnblogs.com/xhq1024/p/12125290.html<br>
 * <p>
 * 线程池添加任务时顺序
 * <p>
 * 1. 活动线程小于核心线程先创建新线程执行任务 <br>
 * 2. 活动线程等于核心线程时将任务加入任务队列 <br>
 * 3. 任务队列满时并且活动线程小于做大线程数
 * 
 * @date 2021/01/10
 */
public class ThreadPoolTest {
    // 线程池
    private static ThreadPoolExecutor pool = null;
    // 核心线程数
    private static final int corePoolSize = 2;
    // 最大线程数
    private static final int maximumPoolSize = 5;
    // 非核心线程空闲多久销毁时间
    private static final long keepAliveTime = 60L;
    // 任务队列大小
    private static int queueSize = 20;

    static {
        init(corePoolSize, maximumPoolSize, keepAliveTime, queueSize);
    }

    public static void init(int corePoolSize, int maximumPoolSize, long keepAliveTime, int queueSize) {
        synchronized (ThreadPoolTest.class) {
            if (pool == null) {
                BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(queueSize);
                pool =
                    new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue);
            }
        }
    }

    public static boolean addTask(String msg) {
        try {
            pool.execute(() -> {
                System.out.println(Thread.currentThread().getName() + ": " + msg);
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
            return true;
        } catch (RejectedExecutionException e) {
            System.out.println("队列已满,添加任务失败" + pool.getQueue().size());
        } catch (Exception e) {
            System.out.println("其他异常");
            e.printStackTrace();
        }
        return false;

    }

    public static void main(String[] args) throws InterruptedException {
        int i = 0;
        while (i < 150) {
            if (!addTask(i++ + "")) {
                Thread.sleep(20 * 1000);
            }
            // long time = (long)(Math.random() * 3000 + 1000);
        }
    }

}
